//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <PowerInc.h>
_ELASTOS_NAMESPACE_USING
#include <PowerFunc.h>
#include <VirtualDevice.h>
#include <PowerManager.h>

static PowerManager powerManager;
Boolean UpdateTaskKeepMode(int task_id,CVirtualDevice *pvd,UInt32 dev_mode,_ELASTOS Boolean keep_on);
Boolean UpdateTaskDevMode(int task_id,CVirtualDevice *pvd,UInt32 dev_mode);
Boolean UpdateTaskChangeInterval(int task_id,CVirtualDevice *pvd,UInt32 interval);
void Power_CallbackTaskChange(int eType, int nCode, void * pParam);
extern"C" int Power_SetCpuMode(int ThreadID,UInt32 NewMode);
extern"C" UInt32 Power_GetCpuMode();
extern"C" UInt32 Power_GetPolicy();
extern"C" int Power_SetPolicy(int ThreadID,UInt32 Policy);
ECode PowerManager::Read(
    /* [in] */ Int64 u64Offset,
    /* [in] */ Int32 bytesToRead,
    /* [out] */ MemoryBuf * pBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode PowerManager::Write(
    /* [in] */ Int64 u64Offset,
    /* [in] */ const MemoryBuf & buffer,
    /* [out] */ Int32 * pBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode PowerManager::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ const MemoryBuf & inBuffer,
    /* [out] */ MemoryBuf * pOutBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    switch (nControlCode) {
        case 0:{//means SetMode
            UInt32 * t=(UInt32*)inBuffer.GetPayload();
            int * task_id=(int*)t;
            UInt32 *mode=++t;
            if (Power_SetCpuMode(*task_id,*mode) < 0) {
                goto Exit;
            }
            break;
        }
        case 1:{//means SetPolicy
            UInt32 * t=(UInt32*)inBuffer.GetPayload();
            int * task_id=(int*)t;
            UInt32 *policy_type=++t;
            if (Power_SetPolicy(*task_id,*policy_type) < 0) {
                goto Exit;
            }
            break;
        }
        case 2:{//means InitDevPowerMode
            UInt32 * t=(UInt32*)inBuffer.GetPayload();
            int task_id=(int)t[0];
            CVirtualDevice *pvd=(CVirtualDevice *)t[1];
            UInt32 DevMode=t[2];
            UpdateTaskDevMode(task_id,pvd,DevMode);
            break;
        }
        case 3:{//means KeepSpecifiedDevMode
            UInt32 * t=(UInt32*)inBuffer.GetPayload();
            int task_id=(int)t[0];
            CVirtualDevice *pvd=(CVirtualDevice *)t[1];
            UInt32 DevMode=t[2];
            Boolean KeepMode=(Boolean)t[3];
            UpdateTaskKeepMode(task_id,pvd,DevMode,KeepMode);
            break;
        }
        case 4:{//means SetChangeModeInterval
            UInt32 * t=(UInt32*)inBuffer.GetPayload();
            int task_id=(int)t[0];
            CVirtualDevice *pvd=(CVirtualDevice *)t[1];
            UInt32 Interval=t[2];
            UpdateTaskChangeInterval(task_id,pvd,Interval);
            break;
        }
        case 10:{//means GetMode
            UInt32 mode=Power_GetCpuMode();
            if (pOutBuffer == NULL) {
                return E_INVALID_ARGUMENT;
            }
            assert(pOutBuffer->GetCapacity() >= (int)sizeof(UInt32));
            pOutBuffer->Copy((Byte*)&mode, (int)sizeof(UInt32));
            break;
        }
        case 11:{//means GetPolicy
            UInt32 policy=Power_GetPolicy();
            if (pOutBuffer == NULL) {
                return E_INVALID_ARGUMENT;
            }
            assert(pOutBuffer->GetCapacity () >= (int)sizeof(UInt32));
            pOutBuffer->Copy((Byte *)&policy, (int)sizeof(UInt32));
            break;
        }
        default:break;
    }
    return NOERROR;
Exit:
    return E_FAIL;
}

/////////////////////////////////////////////////////////////////////
EXTERN IDeviceDriver * CDECL CreatePowerManager(uint_t uDeviceNo, void *pvParameter)
{
#if defined(_win32) || defined(_wince)
    if (Power_Initialize() != 0) return NULL;//surport later.
#endif
    PowerManager * pPowerManager = &powerManager;
    if(pPowerManager)DebugPrint("add power manager ok\n");
    return (IDeviceDriver *)pPowerManager;
}
